package com.yang.springcloudalibaba.dao;

import com.yang.springcloud.pojo.Menu;
import com.yang.springcloud.pojo.RoleMenus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

@Repository
public class MenuImp implements MenuDao{
    @Autowired
    DataSource dataSource;

    Connection conn;
    PreparedStatement pstmt;

    @Override
    public Map<String, Object> queryMenu(int menuid) {
        ResultSet rs;
        Menu menu = new Menu();

        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM menu WHERE id = ?");
            pstmt.setInt(1,menuid);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                menu.setId(id);
                String name = rs.getString("name");
                menu.setName(name);
                int parentMenuId = rs.getInt("parent_menu_id");
                menu.setParentMenuId(parentMenuId);
                Date createdAt = rs.getDate("created_at");
                menu.setCreatedAt(createdAt);
                Date updatedAt = rs.getDate("updated_at");
                menu.setUpdatedAt(updatedAt);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        getMenuList(menu);

        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("massage", "成功");
        msg.put("data", menu);
        msg.put("code", 200);
        return msg;
    }

    @Override
    public void getMenuList(Menu bm) {
        ResultSet rs;
        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM menu WHERE parent_menu_id = ?");
            pstmt.setInt(1, bm.getId());
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int parentMenuId = rs.getInt("parent_menu_id");
                Date createdAt = rs.getDate("created_at");
                Date updatedAt = rs.getDate("updated_at");

                Menu s = new Menu(id, name, parentMenuId, createdAt, updatedAt);
                bm.getSubmenuList().add(s);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


        if (bm.getSubmenuList() != null) {
            for (Menu m : bm.getSubmenuList()) {
                getMenuList(m);
            }
        }
    }

    @Override
    public Map<String, Object> queryRoleMenu(int menuid, int roleid) {
        ResultSet rs;
        Menu menu = new Menu();
        RoleMenus s = new RoleMenus();

        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM menu WHERE id = ?");
            pstmt.setInt(1,menuid);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                menu.setId(id);
                String name = rs.getString("name");
                menu.setName(name);
                int parentMenuId = rs.getInt("parent_menu_id");
                menu.setParentMenuId(parentMenuId);
                Date createdAt = rs.getDate("created_at");
                menu.setCreatedAt(createdAt);
                Date updatedAt = rs.getDate("updated_at");
                menu.setUpdatedAt(updatedAt);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE menu_id = ? and role_id = ?");
            pstmt.setInt(1, menuid);
            pstmt.setInt(2, roleid);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                s.setId(id);
                int roleId = rs.getInt("role_id");
                s.setRoleId(roleId);
                int menuId = rs.getInt("menu_id");
                s.setMenuId(menuId);

            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (s.getId() != 0){
            menu.setThisRoleMenu(true);
        }
        getRoleMenuList(menu, roleid);

        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("massage", "成功");
        msg.put("data", menu);
        msg.put("code", 200);
        return msg;
    }

    @Override
    public void getRoleMenuList(Menu bm, int roleid) {
        ResultSet rs;
        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM menu WHERE parent_menu_id = ?");
            pstmt.setInt(1, bm.getId());
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int parentMenuId = rs.getInt("parent_menu_id");
                Date createdAt = rs.getDate("created_at");
                Date updatedAt = rs.getDate("updated_at");

                Menu s = new Menu(id, name, parentMenuId, createdAt, updatedAt);
                bm.getSubmenuList().add(s);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (bm.getSubmenuList() != null) {
            for (Menu m : bm.getSubmenuList()) {
                RoleMenus s = new RoleMenus();
                try {
                    conn = dataSource.getConnection();
                    pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE menu_id = ? and role_id = ?");
                    pstmt.setInt(1, m.getId());
                    pstmt.setInt(2, roleid);
                    rs = pstmt.executeQuery();
                    while (rs.next()) {
                        int id = rs.getInt("id");
                        s.setId(id);
                        int roleId = rs.getInt("role_id");
                        s.setRoleId(roleId);
                        int menuId = rs.getInt("menu_id");
                        s.setMenuId(menuId);

                    }
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                System.out.println("关联关系：" + s.getId());
                if (s.getId() != 0){
                    m.setThisRoleMenu(true);
                }
                getRoleMenuList(m, roleid);
            }
        }
    }

    @Override
    public Map<String, Object> queryRoleMenuAsync(int menuid, int roleid) throws InterruptedException {
        ResultSet rs;
        Menu menu = new Menu();
        RoleMenus s = new RoleMenus();

        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM menu WHERE id = ?");
            pstmt.setInt(1,menuid);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                menu.setId(id);
                String name = rs.getString("name");
                menu.setName(name);
                int parentMenuId = rs.getInt("parent_menu_id");
                menu.setParentMenuId(parentMenuId);
                Date createdAt = rs.getDate("created_at");
                menu.setCreatedAt(createdAt);
                Date updatedAt = rs.getDate("updated_at");
                menu.setUpdatedAt(updatedAt);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE menu_id = ? and role_id = ?");
            pstmt.setInt(1, menuid);
            pstmt.setInt(2, roleid);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                s.setId(id);
                int roleId = rs.getInt("role_id");
                s.setRoleId(roleId);
                int menuId = rs.getInt("menu_id");
                s.setMenuId(menuId);

            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (s.getId() != 0){
            menu.setThisRoleMenu(true);
        }
        getRoleMenuListAsync(menu, roleid);

        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("massage", "成功");
        msg.put("data", menu);
        msg.put("code", 200);
        return msg;
    }

    @Override
    public void getRoleMenuListAsync(Menu bm, int roleid) throws InterruptedException {
        AtomicReference<ResultSet> rs = new AtomicReference<>();

        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM menu WHERE parent_menu_id = ?");
            pstmt.setInt(1, bm.getId());
            rs.set(pstmt.executeQuery());
            while (rs.get().next()) {
                int id = rs.get().getInt("id");
                String name = rs.get().getString("name");
                int parentMenuId = rs.get().getInt("parent_menu_id");
                Date createdAt = rs.get().getDate("created_at");
                Date updatedAt = rs.get().getDate("updated_at");

                Menu s = new Menu(id, name, parentMenuId, createdAt, updatedAt);
                bm.getSubmenuList().add(s);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (bm.getSubmenuList() != null) {
            CountDownLatch latch = new CountDownLatch(4);
            for (int o = 0; o < 4; o++) {

                int finalO = o;
                new Thread(()-> {
                    for (Menu m : bm.getSubmenuList().subList(finalO*2, (finalO+1)*2)) {
                        RoleMenus s = new RoleMenus();
                        try {
                            conn = dataSource.getConnection();
                            pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE menu_id = ? and role_id = ?");
                            pstmt.setInt(1, m.getId());
                            pstmt.setInt(2, roleid);
                            rs.set(pstmt.executeQuery());
                            while (rs.get().next()) {
                                int id = rs.get().getInt("id");
                                s.setId(id);
                                int roleId = rs.get().getInt("role_id");
                                s.setRoleId(roleId);
                                int menuId = rs.get().getInt("menu_id");
                                s.setMenuId(menuId);

                            }
                            conn.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                        System.out.println("关联关系：" + s.getId());
                        if (s.getId() != 0) {
                            m.setThisRoleMenu(true);
                        }
                        getRoleMenuList(m, roleid);
                    }

                    latch.countDown();
                }).start();
            }

            latch.await();
        }
    }

    @Override
    public Map<String, Object> queryMysMenu(int menuid, int roleid) {
        return null;
    }

    @Override
    public void getMysMenuList(Menu bm, int roleid) {

    }

    @Override
    public Map<String, Object> insertRoleMenu(int roleid, Menu menu) {

        ResultSet rs;

        RoleMenus s = new RoleMenus();
        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE role_id = ? and menu_id = ?");
            pstmt.setInt(1, roleid);
            pstmt.setInt(2, menu.getId());
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                s.setId(id);
                int roleId = rs.getInt("role_id");
                s.setRoleId(roleId);
                int menuId = rs.getInt("menu_id");
                s.setMenuId(menuId);

            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("关联关系：" + s.getId());
        if (menu.isThisRoleMenu() == true) {
            if (s.getId() == 0) {
                int i;
                try {
                    conn = dataSource.getConnection();
                    pstmt = conn.prepareStatement("insert into role_menus (role_id,menu_id) values(?,?)");
                    pstmt.setInt(1, roleid);
                    pstmt.setInt(2, menu.getId());
                    i = pstmt.executeUpdate();
                    System.out.println(i);

                    pstmt.close();
                    conn.close();

                }catch (Exception e){
                    e.printStackTrace();
                }
                menu.setThisRoleMenu(true);
            }
        }else{
            if (s.getId() != 0){
                int i;
                try {
                    conn = dataSource.getConnection();
                    pstmt = conn.prepareStatement("delete from role_menus where id = ?");
                    pstmt.setInt(1, s.getId());

                    i = pstmt.executeUpdate();
                    System.out.println(i);

                    pstmt.close();
                    conn.close();

                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

        putRoleMenuList(roleid, menu);

        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("massage", "插入成功");
        msg.put("data", null);
        msg.put("code", 200);
        return msg;
    }

    @Override
    public void putRoleMenuList(int roleid, Menu menu) {
        ResultSet rs;

        for (Menu m : menu.getSubmenuList()) {
            RoleMenus s = new RoleMenus();
            try {
                conn = dataSource.getConnection();
                pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE role_id = ? and menu_id = ?");
                pstmt.setInt(1, roleid);
                pstmt.setInt(2, m.getId());
                rs = pstmt.executeQuery();
                while (rs.next()) {
                    int id = rs.getInt("id");
                    s.setId(id);
                    int roleId = rs.getInt("role_id");
                    s.setRoleId(roleId);
                    int menuId = rs.getInt("menu_id");
                    s.setMenuId(menuId);

                }
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println("关联关系：" + s.getId());
            if (m.isThisRoleMenu() == true) {
                if (s.getId() == 0) {
                    int i;
                    try {
                        conn = dataSource.getConnection();
                        pstmt = conn.prepareStatement("insert into role_menus (role_id,menu_id) values(?,?)");
                        pstmt.setInt(1, roleid);
                        pstmt.setInt(2, m.getId());
                        i = pstmt.executeUpdate();
                        System.out.println(i);

                        pstmt.close();
                        conn.close();

                    }catch (Exception e){
                        e.printStackTrace();
                    }
                    m.setThisRoleMenu(true);
                }
            }else{
                if (s.getId() != 0){
                    int i;
                    try {
                        conn = dataSource.getConnection();
                        pstmt = conn.prepareStatement("delete from role_menus where id = ?");
                        pstmt.setInt(1, s.getId());

                        i = pstmt.executeUpdate();
                        System.out.println(i);

                        pstmt.close();
                        conn.close();

                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }

            putRoleMenuList(roleid, m);
        }
    }

    @Override
    @Transactional
    public Map<String, Object> insertRoleMenuAsync(int roleid, Menu menu) throws InterruptedException {

        ResultSet rs;

        RoleMenus s = new RoleMenus();
        try {
            conn = dataSource.getConnection();
            pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE role_id = ? and menu_id = ?");
            pstmt.setInt(1, roleid);
            pstmt.setInt(2, menu.getId());
            rs = pstmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                s.setId(id);
                int roleId = rs.getInt("role_id");
                s.setRoleId(roleId);
                int menuId = rs.getInt("menu_id");
                s.setMenuId(menuId);

            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("关联关系：" + s.getId());
        if (menu.isThisRoleMenu() == true) {
            if (s.getId() == 0) {
                int i;
                try {
                    conn = dataSource.getConnection();
                    pstmt = conn.prepareStatement("insert into role_menus (role_id,menu_id) values(?,?)");
                    pstmt.setInt(1, roleid);
                    pstmt.setInt(2, menu.getId());
                    i = pstmt.executeUpdate();
                    System.out.println(i);

                    pstmt.close();
                    conn.close();

                }catch (Exception e){
                    e.printStackTrace();
                }
                menu.setThisRoleMenu(true);
            }
        }else{
            if (s.getId() != 0){
                int i;
                try {
                    conn = dataSource.getConnection();
                    pstmt = conn.prepareStatement("delete from role_menus where id = ?");
                    pstmt.setInt(1, s.getId());

                    i = pstmt.executeUpdate();
                    System.out.println(i);

                    pstmt.close();
                    conn.close();

                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }

        putRoleMenuListAsync(roleid, menu);

        Map<String, Object> msg = new HashMap<String, Object>();
        msg.put("massage", "插入成功");
        msg.put("data", null);
        msg.put("code", 200);
        return msg;
    }

    @Override
    @Transactional
    public void putRoleMenuListAsync(int roleid, Menu menu) throws InterruptedException {
        AtomicReference<ResultSet> rs = new AtomicReference<>();

        CountDownLatch latch = new CountDownLatch(4);
        for (int o = 0; o < 4; o++) {

            int finalO = o;
            new Thread(()-> {
                for (Menu m : menu.getSubmenuList().subList(finalO *2, (finalO +1)*2)) {
                    RoleMenus s = new RoleMenus();
                    try {
                        conn = dataSource.getConnection();
                        pstmt = conn.prepareStatement("SELECT * FROM role_menus WHERE role_id = ? and menu_id = ?");
                        pstmt.setInt(1, roleid);
                        pstmt.setInt(2, m.getId());
                        rs.set(pstmt.executeQuery());
                        while (rs.get().next()) {
                            int id = rs.get().getInt("id");
                            s.setId(id);
                            int roleId = rs.get().getInt("role_id");
                            s.setRoleId(roleId);
                            int menuId = rs.get().getInt("menu_id");
                            s.setMenuId(menuId);

                        }
                        conn.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    System.out.println("关联关系：" + s.getId());
                    if (m.isThisRoleMenu() == true) {
                        if (s.getId() == 0) {
                            int i;
                            try {
                                conn = dataSource.getConnection();
                                pstmt = conn.prepareStatement("insert into role_menus (role_id,menu_id) values(?,?)");
                                pstmt.setInt(1, roleid);
                                pstmt.setInt(2, m.getId());
                                i = pstmt.executeUpdate();
                                System.out.println(i);

                                pstmt.close();
                                conn.close();

                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            m.setThisRoleMenu(true);
                        }
                    } else {
                        if (s.getId() != 0) {
                            int i;
                            try {
                                conn = dataSource.getConnection();
                                pstmt = conn.prepareStatement("delete from role_menus where id = ?");
                                pstmt.setInt(1, s.getId());

                                i = pstmt.executeUpdate();
                                System.out.println(i);

                                pstmt.close();
                                conn.close();

                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }

                    putRoleMenuList(roleid, m);
                }

                latch.countDown();
            }).start(); // 启动线程
        }

        latch.await();
    }
}
